import java.net.*;
import java.io.*;
import java.util.*;

public class GameServer implements Runnable{

	public static final int DEFAULT_PORT = 5656;
	private int port;
	private int clientNum=0;
	int [] cards=new int[54];
	
	ServerSocket server;
	Random rand = new Random();
	Vector<Player> clients=new Vector<Player>();
	Table table;
	
	public GameServer(){
		this(DEFAULT_PORT);
	}
		
	public GameServer(int port){
		this.port=port;
		try{
			server=new ServerSocket(this.port);
			}catch (IOException e) {
               e.printStackTrace();
         	}
        table=new Table();
        table.setGameState(Table.WAIT_JOIN);
        System.out.println("Server Start"); 
	}
	
	public void processMsg(String str){
		int cmd;
		cmd=Connection.getCmd(str);
		switch(cmd){
			case Connection.CMD_JOIN: playerJoin(str);break;
			case Connection.CMD_READY: playerReady(str);break;
			case Connection.CMD_AUCTION: auction(str);break;
			case Connection.CMD_PLAY: play(str);break;
			case Connection.CMD_WIN: win(str);break;
		}
	}
				
	public void run(){	
		try{
			while(true){
        		Socket socket=server.accept();
        		Connection c=new Connection(socket);
        		c.sendMsg("cmd="+Connection.CMD_SETID+"&ID="+clientNum);
				Player client=new Player(clientNum);
				client.setConn(c);
				clients.add(clientNum,client);
				clientNum++;
				ServerThread st=new ServerThread(client,this);
				st.start();
        	}
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
     
    private void playerJoin(String str){
    	int id;
    	try{
    		id=Connection.getIntValue("ID",str);  	
    		if(table.getGameState()==Table.WAIT_JOIN) {
    			String msg=table.tableInfo();
    			msg="cmd="+Connection.CMD_TABLEINFO+"&"+msg;
    			(clients.get(id)).conn.sendMsg(msg);
    			msg=table.addPlayer(clients.get(id));
    			table.showMsg(msg);
    			}
    		else (clients.get(id)).conn.sendMsg("cmd="+Connection.CMD_FULL);
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    	}
    
     //发牌
    private void dealCards(){
     	String msg;
     	for(int i=0;i<54;i++) cards[i]=i+1;
     	int [] newCards=new int[17];
        
     	for(int i=0;i<3;i++){//分别为3个玩家发放随机的17张牌
     		msg="cards=";
     		for(int j=0;j<17;j++){
     			int k=rand.nextInt(54);
     			while(cards[k]==0) k=(k+1)%54;
     			newCards[j]=cards[k];
     			msg=msg+cards[k]+",";
     			cards[k]=0;
     		}
     		msg="cmd="+Connection.CMD_DEALCARDS+"&"+msg;
     		table.players[i].conn.sendMsg(msg);
     		table.players[i].receiveCards(newCards);
     		}
     		     		
     	System.out.print("Last three cards:");
     	int []tempCards=new int[3];
     	for(int i=0,k=0;i<54;i++){
     		if(cards[i]!=0) {
     			tempCards[k++]=cards[i];
     			}
     		}
		table.setLastCards(tempCards);		 
		int k=rand.nextInt(3);
		table.currentPlayer=k;
		msg="cmd="+Connection.CMD_AUCTION+"&seat="+k+"&bid="+table.bid;
		table.showMsg(msg);
     }   

 	//用于处理叫牌的函数	

    private void auction(String str){
		
		int i=Connection.getIntValue("bid",str);
		String msg;
		if(i>table.bid){ 
			table.landlord=Connection.getIntValue("ID",str);
			table.bid=i;
		}
		
		table.auctionTime+=1;
		if(table.auctionTime==3||table.bid==3){
			table.currentPlayer=((Player)clients.get(table.landlord)).seatNum;
			table.players[table.currentPlayer].receiveCards(table.lastCards);
			msg="cmd="+Connection.CMD_SETLANDLORD
				+"&bid="+table.bid
				+"&ID="+table.players[table.currentPlayer].id
				+"&seat="+table.currentPlayer
				+"&cards="+table.lastCards[0]
				+","+table.lastCards[1]
				+","+table.lastCards[2];
			table.showMsg(msg);
		}	
		else {
			table.currentPlayer=(table.currentPlayer+1)%3;
			msg="cmd="+Connection.CMD_AUCTION
				+"&bid="+table.bid+"&ID="+table.players[table.currentPlayer].id
				+"&seat="+table.currentPlayer;
			table.players[table.currentPlayer].conn.sendMsg(msg);
			}
	}
	
	private void play(String str){
		
		int [] cards=Connection.getCards(str);
		if(table.currentPlayer==Connection.getIntValue("seat",str)){
		if(cards[0]!=0) table.players[Connection.getIntValue("seat",str)].removeCards(cards);
		table.showMsg(str);
		table.currentPlayer=(table.currentPlayer+1)%3;
		}
	}
	
	private void playerReady(String str){
		int id=Connection.getIntValue("id",str);
		((Player)clients.get(id)).setState(Player.READY);
		table.showMsg(str);
		if(table.isReady()) dealCards();
		}
	
	private void win(String str){
		table.newGame();
	}	
}